//
//  TelephoneChargeVC.swift
//  zhonglb_iOS
//
//  Created by lxm on 2021/12/7.
//

import UIKit
import ContactsUI
import RxRelay
import Then
import WebKit

class TelephoneChargeVC: ZMViewController, UITextFieldDelegate {

    //MARK:--------------------属性--------------------
    var operatorLabelLeft : ConstraintMakerEditable?
    
    let viewModel = TelephoneChargeViewModel()
    //MARK:--------------------UI控件--------------------
    @IBOutlet weak var phoneContent: UIView!
    
    @IBOutlet weak var phoneText: UITextField!
    
    @IBOutlet var Items: [TelephoneChargeItemView]!
    
    @IBOutlet weak var lineView: UIImageView!
    
    @IBOutlet weak var bgImg: UIImageView!
    
    @IBOutlet weak var segContent: UIView!
    
    @IBOutlet weak var stackOne: UIStackView!
    
    @IBOutlet weak var stackTwo: UIStackView!
    
    @IBOutlet weak var stackContainer: UIStackView!
        
    @IBOutlet weak var topContainer: UIView!
    
    @IBOutlet weak var webView: UIView!
    @IBOutlet weak var webHeight: NSLayoutConstraint!
    
    lazy var wkWeb: WKWebView = {
        let userContentController = WKUserContentController()
        let wkWebConfig = WKWebViewConfiguration()
        wkWebConfig.userContentController = userContentController
        wkWebConfig.allowsInlineMediaPlayback = true
        let web = WKWebView(frame: CGRect.zero, configuration: wkWebConfig)
        web.scrollView.showsVerticalScrollIndicator = false
        web.backgroundColor = .white
        web.navigationDelegate = self
        web.scrollView.bounces = false
        webView.addSubview(web)
        web.snp.makeConstraints { (make) in
            make.edges.equalToSuperview()
        }
        return web
    }()
    
//    let web = WKWebView()

    var seg : XMIndexHeaderView!

    let loadingView = XMLoadingView()
    
    let operatorLabel = ZMUtil.label(title: "四川移动", color: UIColor.zm.color333333(), font: UIFont.systemFont(ofSize: 12))
    
    var historyView = HistoryView()
    //MARK:--------------------生命周期--------------------
    override func viewDidLoad() {
        super.viewDidLoad()
        setUI()
        addConstraints()
        bindAction()
        viewModel.laodConfigInfo()
        loadH5()
    }
    
    override func viewWillLayoutSubviews() {
        super.viewWillLayoutSubviews()
        bgImg.style.Gradient(colors: ["#DF3C2C".zm.hex().cgColor, UIColor.zm.RGBA(r: 223, g: 60, b: 44, a: 0).cgColor], locations: [0.3, 1], startPoint: CGPoint(x: 0.5, y: 0), endPoint: CGPoint(x: 0.5, y: 1))
    }
    //MARK:--------------------UI--------------------
    func setUI() {
        title = "话费充值"
        hbd_barShadowHidden = false
//        setRightCustomBtn(titleStr: "充值记录", color: UIColor.zm.color666666(), font: UIFont.systemFont(ofSize: 14))
        phoneText.delegate = self//InputMananger.shard.onlyNumber
        
        phoneContent.addSubview(operatorLabel)
        operatorLabel.snp.makeConstraints { make in
            make.centerY.equalToSuperview()
            self.operatorLabelLeft = make.left.equalToSuperview().offset(18 + 0 + 8)
        }
        operatorLabel.isHidden = true
        phoneText.attributedPlaceholder = "请输入充值手机号".zm.attributedStr(attrs: [.foregroundColor : UIColor.white])
        
        Items = Items.sorted { o, t in
            o.tag < t.tag
        }
        makeSeg()
        
//        view.addSubview(web)
//        web.layer.cornerRadius = 16
//        web.layer.masksToBounds = true
    }
    
    func makeSeg() {
        let config  = XMIndexHeaerViewConfig()
        config.font = UIFont.systemFont(ofSize: 16, weight: .regular)
        config.fontColor  = UIColor.black
        config.selectFont = UIFont.systemFont(ofSize: 16, weight: .medium)
        config.selectFontColr = Style.mainColor
       
        seg = XMIndexHeaderView(frame: CGRect(x: 0, y: 0, width: SCREEN_W - 30, height: 49), withTitleArray:["快充", "慢充"], animation: false)!
        seg.lineColor = Style.mainColor
        seg.lineWidth = 48
        seg.config = config
        seg.delegateXM = self
        segContent.addSubview(seg!)
    }
    
    func changeOp(title : String) {
        let titleSize = title.zm.size(width: 400, height: 40, font: phoneText.font!, needDefaulHeight: false)
        if let r = self.operatorLabelLeft {
            r.constraint.update(offset: titleSize.width + 18 + 8)
            operatorLabel.layoutIfNeeded()
        }
    }
    
    func addConstraints() {
//        web.snp.makeConstraints { make in
//            make.top.equalTo(self.topContainer.snp.bottom).offset(15)
//            make.left.equalTo(view).offset(15)
//            make.right.equalTo(view).offset(-15)
//            make.bottom.lessThanOrEqualTo(view.safeAreaLayoutGuide).offset(-15)
//            make.height.equalTo(0).priority(.low)
//        }
    }
    
    //MARK:--------------------methods--------------------
    func bindAction() {
        Items.forEach { item in
            item.onClick = { [weak self] in
                guard let self = self else{return}
                let meals = self.viewModel.mealList.value.filter({$0.type == self.viewModel.currentType.value})
                let index = item.tag - 100
                if meals.count > index {
                    self.viewModel.currentSelectIndex.accept(index)
                }
            }
        }
        
        phoneText.rx.text.orEmpty.debounce(.milliseconds(500), scheduler: MainScheduler.instance).filter({$0.zm.isPhoneNum()}).subscribe(onNext:{ [unowned self] resp in
//            self.onSearchPhone(phone : resp)
        }).disposed(by: disposeBag)
        
        Observable.combineLatest(viewModel.phoneInfo, phoneText.rx.text.orEmpty).subscribe(onNext:{ [unowned self] resp in
            self.changeOp(title: resp.1)
            if let r = resp.0 {
                self.operatorLabel.isHidden = resp.1.count < 11 || r.phone != resp.1
                self.operatorLabel.text = r.province + r.company
            } else {
                self.operatorLabel.text = ""
            }
        }).disposed(by: disposeBag)
        
        
        
        Observable.combineLatest(viewModel.mealList, viewModel.currentType).subscribe(onNext:{ [unowned self] resp in
            let meals = resp.0.filter({$0.type == resp.1})
            self.viewModel.currentSelectIndex.accept(meals.count > 0 ? 0 : nil)
            let width = (SCREEN_W - 30 - 32 - 12) / 3
            for i in 0 ..< self.Items.count {
                let itemView = self.Items[i]
                if meals.count > i {
                    let item = meals[i]
                    itemView.price.text = item.faceValue.zm.toString(keep: 2)
                    itemView.znPrice.text = "售价\(item.sellPrice.zm.toString(keep: 2))元"
                    itemView.znPrice.isHidden = false
                    itemView.unit.isHidden = false
                    itemView.isHidden = false
                } else {
                    itemView.isHidden = true
                    itemView.price.text = "未上架"
                    itemView.znPrice.text = ""
                    itemView.unit.isHidden = true
                    itemView.znPrice.isHidden = true
                }
                
                if meals.count > 1 {
                    itemView.snp.makeConstraints { make in
                        make.width.equalTo(width)
                    }
                } else {
                    itemView.snp.removeConstraints()
                }
            }
            
            
            
            stackContainer.alignment = meals.count > 1 ? .leading : .fill
            self.stackTwo.isHidden = meals.count <= 3
        }).disposed(by: disposeBag)
        
        // 绑定选中
        viewModel.currentSelectIndex.subscribe(onNext:{ [unowned self] resp in
            Items.forEach({$0.isSelect = false})
            if let v = self.Items.first(where: {$0.tag == (resp ?? -1) + 100}) {
                v.isSelect = true
            }
        }).disposed(by: disposeBag)
        
        historyView.onRemove = { [weak self] index in
            guard let self = self else {return}
            self.viewModel.deletePhoneCache(phone: self.viewModel.getPhoneCache()[index])
            let afterHis = self.viewModel.getPhoneCache()
            self.historyView.dataArray = afterHis
            if afterHis.count == 0 {
                self.historyView.removeFromSuperview()
            }
        }
        
        historyView.onSelectRow = { [weak self] index in
            guard let self = self else {return}
            let data = self.viewModel.getPhoneCache()[index]
            self.viewModel.phoneInfo.accept(data)
            self.phoneText.text = data.phone
            self.phoneText.sendActions(for: .valueChanged)
        }
        
        
        ZMPayManager.shard.payCallBack.subscribe(onNext:{ [unowned self] resp in
            switch resp {
            case .success:
                // 支付成功
                router.push("xm://main/telephone/record")
                break
            default:
                ZMToast.showToast(title: resp.rawValue)
            }
        }).disposed(by: disposeBag)
        
//        web.scrollView.rx.observe(CGSize.self, "contentSize").subscribe(onNext:{ [unowned self, weak web] resp in
//            if let size = resp, let web = web {
//                let h = size.height
//                web.snp.updateConstraints { make in
//                    make.height.equalTo(h).priority(.low)
//                }
//            }
//        }).disposed(by: disposeBag)
        
        wkWeb.scrollView.rx.observeWeakly(CGSize.self, "contentSize").subscribe(onNext: { [unowned self] (change) in
            self.webHeight.constant = change!.height
        }).disposed(by: disposeBag)
    }
    
    func onSearchPhone(phone: String) {
        if viewModel.phoneInfo.value?.phone == phone {return}
        viewModel.phoneInfo.accept(nil)
        TelephoneAPI.phone_info(params: ["phone" : phone]).rxRequest(type: TelePhoneModels.PhoneInfo.self).subscribe(onNext:{ [unowned self] resp in
            self.viewModel.phoneInfo.accept(resp)
        }, onError: { _ in
            self.viewModel.phoneInfo.accept(nil)
        }).disposed(by: disposeBag)
    }
    
    //MARK: 充值
    @IBAction func onCharge(_ sender: Any) {
        if phoneText.text!.zm.isEmpty() {
            ZMToast.showToast(title: "请输入电话号码")
            return
        }
        if phoneText.text!.zm.isPhoneNum() == false {
            ZMToast.showToast(title: "电话号码格式不正确")
            return
        }
        let meals = viewModel.mealList.value.filter({$0.type == viewModel.currentType.value})

        guard let index = viewModel.currentSelectIndex.value, meals.count > index else {
            ZMToast.showToast(title: "请选择套餐")
            return
        }
        // 获取订单编号
        let meal = meals[index]
        ZMToast.showActivity()
        TelephoneAPI.create_order(["denominationId" : meal.id, "mobile" : phoneText.text!, "payType" : "alipay", "type" : meal.type]).rxRequest(type: [String : Any].self).subscribe(onNext:{ [unowned self] resp in
            ZMToast.hiddenActivity()
            self.showPay(money: meal.sellPrice.zm.toString(keep: 2), orderNo: JSON(resp)["orderNo"].stringValue)
        }).disposed(by: self.disposeBag)
        
    }
    
    @IBAction func onRecord(_ sender: Any) {
        router.push("xm://main/telephone/record")
    }
    
    
    
    func showPay(money : String, orderNo : String) {
        view.endEditing(true)
        let v = ZMUtil.loadNibViewFullScreen(nibName: OrderChoosePayView.self)
        v.price.text = money
        v.payMoney = Double(money) ?? 0
        v.onPayCallback = { [weak self, weak v] type in
            guard let v = v, let self = self else {return}
            var payType = ""
            switch type {
                case .alipay:
                    payType = "alipay"
                    break;
                case .wechat:
                    payType = "weixin"
                    break;
                case .balancePay:
                    payType = "yue"
                case .ckPay:
                    payType = "mallYue"
                case .integral:
                    payType = "integral"
            }
            
            var pa = ["orderNo" : orderNo, "payType" : payType] as [String : Any]
            if type == .balancePay || type == .ckPay {
                CommonService.shared.showPsdInput(title : "请输入交易密码", money: money, left : "", right : "") { psd, close in
                    pa["tradePwd"] = psd
                    self.sendPay(pa: pa, orderNo: orderNo, payType: payType) { ok in
                        close(ok)
                        v.removeFromSuperview()
                    }
                }
            } else {
                self.sendPay(pa: pa, orderNo: orderNo, payType: payType) { ok in
                    v.removeFromSuperview()
                }
            }
        }
        APPWindow?.addSubview(v)
    }
    
    func sendPay(pa : [String : Any], orderNo : String, payType : String, complete:@escaping (_ ok : Bool)->()) {
        ZMToast.showActivity()
        VIPMallAPI.payInfo(pa).rxRequest(type: [String : Any].self).subscribe(onNext:{ [unowned self] resp in
            ZMToast.hiddenActivity()
            if payType == "yue" || payType == "mallYue" {
                // 支付成功
                router.push("xm://main/telephone/record")
            } else {
                let payStr = JSON(resp)["alipayRequest"].stringValue
                if payType == "weixin" {
                    ZMPayManager.shard.wechatPay(resp, orderNum: orderNo)
                } else {
                    ZMPayManager.shard.aliPayWithInfo(payStr, orderNum: orderNo)
                }
            }
            complete(true)
        }, onError: { _ in
            complete(false)
        }).disposed(by: self.disposeBag)
    }
    
    // 加载h5
    func loadH5() {
        CommonAPI.getDetail(ArticleType.phoneRule.rawValue).rxRequest(type: [String : Any].self).subscribe(onNext:{ [unowned self] resp in
            let json = JSON(resp)
            self.wkWeb.loadHTMLString(json["content"].stringValue.zm.htmlBigSizeString(), baseURL: nil)
//            self.web.loadHTMLString(json["content"].stringValue.zm.htmlBigSizeString(), baseURL: nil)
        }).disposed(by: disposeBag)
    }
    
    //MARK:--------------------delegate--------------------
    func textField(_ textField: UITextField, shouldChangeCharactersIn range: NSRange, replacementString string: String) -> Bool {
        let regex = "^[0-9]*$"
        let ok = NSPredicate(format: "SELF MATCHES %@",regex).evaluate(with: string)
        return ok
    }
    
    
    func textFieldDidBeginEditing(_ textField: UITextField) {
        let history = viewModel.getPhoneCache()
        if history.count == 0 {return}
        view.addSubview(historyView)
        historyView.dataArray = history
        
        historyView.snp.makeConstraints { make in
            make.top.equalTo(phoneContent.snp.bottom)
            make.right.left.bottom.equalToSuperview()
        }
        lineView.backgroundColor = Style.mainColor
    }
    
    func textFieldDidEndEditing(_ textField: UITextField) {
        historyView.removeFromSuperview()
        lineView.backgroundColor = Style.lineColor
    }

}

extension TelephoneChargeVC: WKNavigationDelegate {
    func webView(_ webView: WKWebView, didFinish navigation: WKNavigation!){
        func webView(_ webView: WKWebView, didFinish navigation: WKNavigation!){
            let imgSize = """
            var imgs = document.getElementsByTagName("img")
            for (var i = 0; i < imgs.length; i++) {
                imgs[i].setAttribute('width', '99%')
            }
            """
            webView.evaluateJavaScript(imgSize, completionHandler: nil)
            
            webView.evaluateJavaScript("""
                      var oMeta = document.createElement('meta');
                      oMeta.content = 'width=device-width, initial-scale=1.0, user-scalable=0';
                      oMeta.name = 'viewport';
                      document.getElementsByTagName('head')[0].appendChild(oMeta);
                      """) { flag, error in }
            
        }
        
    }
}

extension TelephoneChargeVC : XMIndexHeaderViewDelegate {
    func xmIndexHeaderViewDidselected(with index: Int) {
        if index == 0 {
            viewModel.currentType.accept(1)
        } else {
            viewModel.currentType.accept(0)
        }
    }
}


//MARK: --------------------HistoryView--------------------
extension TelephoneChargeVC {
    class HistoryView : UIView, UITableViewDelegate, UITableViewDataSource {
        
        override func touchesBegan(_ touches: Set<UITouch>, with event: UIEvent?) {
            
        }
        
        var tableH : ConstraintMakerEditable?
        
        var dataArray = [TelePhoneModels.PhoneInfo]() {
            didSet {
                tableView.reloadData()
                if let th = self.tableH {
                    th.constraint.update(offset: dataArray.count * 67)
                }
            }
        }
        // 移除回掉
        var onRemove : ((_ index : Int)->())?
        
        var onSelectRow : ((_ index : Int)->())?
        
        let tableView = UITableView().then { t in
            t.separatorStyle = .none
        }
        
        override init(frame: CGRect) {
            super.init(frame: frame)
            setUI()
            makeConstraints()
        }
        
        required init?(coder: NSCoder) {
            super.init(coder: coder)
        }
        
        override func awakeFromNib() {
            super.awakeFromNib()
            setUI()
            makeConstraints()
        }
        
        func setUI() {
            backgroundColor = UIColor.zm.color(hexString: "000000", 0.65)
            addSubview(tableView)
            tableView.delegate = self
            tableView.dataSource = self
            tableView.register(HistoryCell.self, forCellReuseIdentifier: "HistoryCell")
        }
        
        func makeConstraints() {
            tableView.snp.makeConstraints { make in
                make.top.right.left.equalToSuperview()
                self.tableH = make.height.equalTo(67 * 3)
            }
        }
        
        func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
            return dataArray.count
        }
        
        func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
            let cell = tableView.dequeueReusableCell(withIdentifier: "HistoryCell") as! HistoryCell
            let data = dataArray[indexPath.row]
            cell.label.text = data.phone
            cell.subLabel.text = data.province + data.company
            cell.close.rx.tap.subscribe(onNext:{ [unowned self] resp in
                if let onRemove = self.onRemove {
                    onRemove(indexPath.row)
                }
            }).disposed(by: cell.disposeBag)
            return cell
        }
        
        func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat {
            return HistoryCell.cellHeight
        }
        
        func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
            tableView.deselectRow(at: indexPath, animated: true)
            if let onSelectRow = self.onSelectRow {
                onSelectRow(indexPath.row)
            }
        }
    }
    
    class HistoryCell : UITableViewCell {
        static var cellHeight : CGFloat = 67
        
        
        var label = ZMUtil.label(title: "13987654321", color: UIColor.zm.color333333(), font: UIFont.systemFont(ofSize: 16))
        var subLabel = ZMUtil.label(title: "四川移动", color: UIColor.zm.color999999(), font: UIFont.systemFont(ofSize: 12))
        var close = ZMUtil.button(image: UIImage.init(named: "guanbi"))
        var sepLine = UIView().then { v in
            v.backgroundColor = UIColor.zm.color(hexString: "000000", 0.1)
        }
        
        var disposeBag = DisposeBag()
        
        
        override init(style: UITableViewCell.CellStyle, reuseIdentifier: String?) {
            super.init(style: style, reuseIdentifier: reuseIdentifier)
            setUI()
        }
        
        required init?(coder: NSCoder) {
            super.init(coder: coder)
            setUI()
        }
        
        func setUI() {
            contentView.addSubview(label)
            contentView.addSubview(subLabel)
            contentView.addSubview(close)
            contentView.addSubview(sepLine)
            label.snp.makeConstraints { make in
                make.top.equalToSuperview().offset(12)
                make.left.equalToSuperview().offset(16)
            }
            subLabel.snp.makeConstraints { make in
                make.top.equalTo(label.snp.bottom).offset(4)
                make.left.equalToSuperview().offset(16)
            }
            close.snp.makeConstraints { make in
                make.centerY.equalToSuperview()
                make.right.equalToSuperview().offset(-16)
            }
            sepLine.snp.makeConstraints { make in
                make.right.equalToSuperview().offset(-16)
                make.left.equalToSuperview().offset(16)
                make.bottom.equalToSuperview()
                make.height.equalTo(0.5)
            }
        }
        
        override func prepareForReuse() {
            super.prepareForReuse()
            disposeBag = DisposeBag()
        }
    }
}


//MARK:--------------------TelephoneChargeItemView--------------------
class TelephoneChargeItemView : UIView {
    
    var onClick : (()->())?
    
    var isSelect = false {
        didSet {
            change()
        }
    }
    public let price = ZMUtil.label(title: "30", color: Style.mainColor, font: Style.FONT_Open_Sans_SemiBold(24))
    public let unit = ZMUtil.label(title: "元", color: Style.mainColor, font: UIFont.systemFont(ofSize: 12, weight: .medium))
    public let znPrice = ZMUtil.label(title: "18.1455", color: Style.mainColor, font: UIFont.systemFont(ofSize: 12, weight: .regular))
    
    override init(frame: CGRect) {
        super.init(frame: frame)
        setUI()
    }
    
    required init?(coder: NSCoder) {
        super.init(coder: coder)
    }
    
    override func awakeFromNib() {
        super.awakeFromNib()
        setUI()
    }
    
    func setUI() {
        let priceStack = UIStackView()
        priceStack.addArrangedSubview(price)
        priceStack.addArrangedSubview(unit)
        priceStack.alignment = .firstBaseline
        priceStack.spacing = 2
        let wholeStack = UIStackView()
        wholeStack.axis = .vertical
        wholeStack.spacing = 1
        wholeStack.addArrangedSubview(priceStack)
        wholeStack.addArrangedSubview(znPrice)
        wholeStack.alignment = .center
        
        addSubview(wholeStack)
        wholeStack.snp.makeConstraints { make in
            make.center.equalToSuperview()
        }
        let tap = UITapGestureRecognizer()
        addGestureRecognizer(tap)
        tap.addTarget(self, action: #selector(onTap))
        change()
    }
    
    @objc func onTap() {
        if let onClick = onClick {
            onClick()
        }
    }
    
    func change() {
        let textColor = isSelect ?  Style.mainColor : UIColor.zm.color333333()
        price.textColor = textColor
        unit.textColor = textColor
        znPrice.textColor = textColor
        backgroundColor = isSelect ? UIColor.zm.color(hexString: "#DE3E26", 0.1) : UIColor.white
        borderWidth = 0.5
        borderColor = isSelect ? "#DE3F26".zm.hex() : UIColor.zm.color(hexString: "#333333", 0.2)
    }
}
